#include "ypicture.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// #include </usr/local/include/jpeglib.h>
// #include </usr/local/include/png.h>

#pragma pack(push, 1)
struct bitmap_header
{
	int16_t type;
	int32_t size; // 图像文件大小
	int16_t reserved1;
	int16_t reserved2;
	int32_t offbits; // bmp图像数据偏移量

	int32_t bisize;   // 本结构大小	
	int32_t width;  // 图像宽
	int32_t height; // 图像高
	int16_t planes;

	int16_t bit_count; // 色深
	int32_t compression;
	int32_t size_img; // bmp数据大小，必须是4的整数倍
	int32_t X_pel;
	int32_t Y_pel;
	int32_t clrused;
	int32_t clrImportant;
};
#pragma pack(0)

static ypic* create_ybmp(struct bitmap_header* hp);
static ypic* jpgTransRgb(uint8_t* data, int32_t size);
// static ypic* pngTransRgb(FILE *fp);

ypic* readBmp(char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL) return NULL;

    struct bitmap_header header;
    fread(&header, sizeof(header), 1, file);
    fseek(file, header.offbits, SEEK_SET);

    ypic *bp = create_ybmp(&header);
    uint8_t *data = bp->data;
    fread(data, bp->size, 1, file);
    
    fclose(file);
    return bp;
}

// 读取jpg图片的数据
// ypic* readJpg(char *filename)
// {
//     // 读取文件数据
//     FILE *file = fopen(filename, "r");
//     if (file == NULL) return NULL;

//     fseek(file, 0, SEEK_END);
//     int32_t size = ftell(file);
//     fseek(file, 0, SEEK_SET);

//     uint8_t *filedata = (uint8_t*)malloc(size);
//     fread(filedata, size, 1, file);
//     fclose(file);

//     // 解码文件数据
//     ypic* pic = jpgTransRgb(filedata, size);

//     return pic;
// }

// 读取 png 图片
// ypic* readPng(char *filename)
// {
//     FILE *file = fopen(filename, "rb");
//     if (file == NULL) return NULL;

//     ypic *pic = pngTransRgb(file);
//     fclose(file);

//     return pic;
// }

// 销毁ybmp
void destory_ypic(ypic* bp)
{
    if (bp != NULL){
        free(bp->data);
        free(bp);
    }
}

static ypic* create_ybmp(struct bitmap_header* hp)
{
    ypic* bp = (ypic*)malloc(sizeof(ypic));
    if (bp == NULL) return NULL;
    bp->width = hp->width;
    bp->height = hp->height;
    bp->bytesPixel = hp->bit_count / 8;
    bp->size = hp->width * hp->height * bp->bytesPixel;
    
    bp->data = (uint8_t*)malloc(bp->size);
    if (bp->data == NULL){
        free(bp);
        return NULL;
    }
    return bp;
}

// static ypic* jpgTransRgb(uint8_t* data, int32_t size)
// {
//     // 1.声明解码结构体，以及错误管理结构体
//     struct jpeg_decompress_struct cinfo;
//     struct jpeg_error_mgr jerr;

//     // 2.使用缺省的出错处理来初始化解码结构体
//     cinfo.err = jpeg_std_error(&jerr);
//     jpeg_create_decompress(&cinfo);

//     // 3.配置该 cinfo ，使其从 jpgdata 中读取 jpgsize 个字节
//     //  这些数据必须是完整的jpeg数据
//     jpeg_mem_src(&cinfo, data, size);

//     // 4. 读取JPEG文件的头，并判断其格式是否合法
//     if (!jpeg_read_header(&cinfo, true)){
//         return NULL;
//     }

//     // 5. 开始解码
//     jpeg_start_decompress(&cinfo);

//     ypic* pic = (ypic*)malloc(sizeof(ypic));
//     pic->width = cinfo.output_width;
//     pic->height = cinfo.output_height;
//     pic->bytesPixel = cinfo.output_components;
//     pic->size = pic->width * pic->height * pic->bytesPixel;
//     pic->data = (uint8_t*)calloc(1, pic->size);

//     // 6. 循环将图片的每一行读出并解码
//     int32_t linesize = cinfo.output_width * cinfo.output_components;
//     while (cinfo.output_scanline < cinfo.output_height)
//     {
//         uint8_t *buffer_array[1];
//         buffer_array[0] = pic->data + cinfo.output_scanline * linesize;
//         jpeg_read_scanlines(&cinfo, buffer_array, 1);
//     }

//     // 7. 解码完成 将 jpeg 相关资源释放掉
//     jpeg_finish_decompress(&cinfo);
//     jpeg_destroy_decompress(&cinfo);

//     uint8_t* p = pic->data;
//     uint8_t t;
//     for (int i=1; i<pic->size; i+=pic->bytesPixel){
//         t = p[i-1];
//         p[i-1] = p[i+1];
//         p[i+1] = t;
//     }

//     return pic;
// }

// static ypic* pngTransRgb(FILE *fp)
// {
// /*************************** 创建 *************************/

//     // 1.1 创建 png 读取结构体
//     png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
//                         NULL, NULL, NULL);
//     if (png == NULL) return NULL;


//     // 1.2 创建 png 信息结构
//     png_infop info = png_create_info_struct(png);  
//     if (!info) {  
//         png_destroy_read_struct(&png, NULL, NULL);   
//         return NULL;  
//     }  

//     // 1.3 设置错误处理
//     if (setjmp(png_jmpbuf(png))){
//         png_destroy_read_struct(&png, &info, NULL);
//         return NULL;
//     }
// /************************** 读取头信息操作 ****************************/

//     // 2.1 初始化 I/O
//     png_init_io(png, fp);
//     png_read_info(png, info);
//     // 2.2 读取文件信息
//     png_uint_32 width, height;
//     int bit_depth, color_type;
//     png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);

// /************************ color_type 处理 ********************************/
//     // 根据PNG文件的特性转换  
//     // 如果位深为16则转换为8位
//     if (bit_depth == 16)
//         png_set_strip_16(png);

//     // 如果颜色类型为调色板 则转换为 RGB
//     if (color_type == PNG_COLOR_TYPE_PALETTE)  
//         png_set_palette_to_rgb(png);  
  
//     // 如果颜色类型为灰度且位深度小于8，则扩展为8位  
//     if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)  
//         png_set_expand_gray_1_2_4_to_8(png);  
  
//     // 如果存在透明色，则将其转换为alpha通道  
//     if (png_get_valid(png, info, PNG_INFO_tRNS))  
//         png_set_tRNS_to_alpha(png);  
  
//     // 对于没有alpha通道的颜色类型，填充alpha通道为0xff  
//     if (color_type == PNG_COLOR_TYPE_RGB ||  
//         color_type == PNG_COLOR_TYPE_GRAY ||  
//         color_type == PNG_COLOR_TYPE_PALETTE)  
//         png_set_filler(png, 0xFF, PNG_FILLER_AFTER);  
  
//     // 将灰度或灰度+alpha转换为RGB 
//     if (color_type == PNG_COLOR_TYPE_GRAY ||  
//         color_type == PNG_COLOR_TYPE_GRAY_ALPHA)  
//         png_set_gray_to_rgb(png);  
  
//     // 更新PNG读取信息结构  
//     png_read_update_info(png, info);  

// /************************* 读取图像数据 *************************/

//     // 为图像数据分配内存
//     png_bytep row_pointers[height];
//     for (png_uint_32 y=0; y<height; ++y){
//         row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
//     }

//     // 读取 png 图像数据到 row_pointers 中
//     png_bytepp row_pointers_copy = row_pointers;
//     png_read_image(png, row_pointers_copy);

//     // 为 rgb数据 分配内存
//     uint8_t *rgbdata = (uint8_t*)malloc(width*height*3*sizeof(uint8_t));
//     if (!rgbdata){
//         // 释放已分配的行指针内存  
//         for (png_uint_32 y = 0; y < height; y++) {  
//             free(row_pointers[y]);  
//         }  
//         // 销毁PNG读取结构  
//         png_destroy_read_struct(&png, &info, NULL);  
//         return NULL;
//     }

//     // 读取 png 数据并转换为rgb数据
//     for (png_uint_32 y = 0; y < height; y++) {  
//         png_bytep row = row_pointers[y];  
//         for (png_uint_32 x = 0; x < width; x++) {  
//             // 每个像素4个字节：RGBA  
//             png_bytep px = &(row[x * 4]);  
//             // 存储RGB数据，忽略Alpha通道  
//             rgbdata[(y * width + x) * 3 + 0] = px[2]; // Red  
//             rgbdata[(y * width + x) * 3 + 1] = px[1]; // Green  
//             rgbdata[(y * width + x) * 3 + 2] = px[0]; // Blue  
//         }  
//     }

//     // 清理：释放行指针内存，销毁PNG读取结构
//     for (png_uint_32 y = 0; y < height; y++) {  
//         free(row_pointers[y]);  
//     }  
//     png_destroy_read_struct(&png, &info, NULL); 

//     ypic *pic = (ypic*)malloc(sizeof(ypic)); 
//     if (!pic){ 
//         free(rgbdata);
//         return NULL;
//     }fprintf(stderr, "%d\n", __LINE__);
//     pic->width = width;
//     pic->height = height;
//     pic->bytesPixel = 3;
//     pic->size = width * height * 3;
//     pic->data = rgbdata;

//     return pic;
// }